#pragma once
#include "vector"
#include "map"
#include "queue"
#include "iostream"
template<class V,class E  = double >
class DijkstraTable{
public:
    explicit DijkstraTable(std::vector<V> Nodes,E defaultMax = 10000) //基本想法是通过Nodes构造DijkstraTable
    {
        int N = Nodes.size();
        m_preNode.resize(N);
        m_TargetDist.resize(N);
        for(int i = 0;i < N ;i ++)
        {
            m_Node2Index[Nodes[i]] = i;
            m_TargetDist[i] = defaultMax;
            m_preNode[i] = Nodes[i];
        }
    }



    E& dist(V node) {return m_TargetDist[m_Node2Index[node]];}
    V& pNode(V node)  {return m_preNode[m_Node2Index[node]];}

    void print()
    {
        auto iter = m_Node2Index.begin();
        for(int i = 0; i < m_preNode.size(); i ++ )
        {
            std::cout << "current Node's:" << iter++->first << " , dist:" << m_TargetDist[i] << " , preNode's:" << m_preNode[i] << std::endl;
        }
    }



private:
    std::map<V,int> m_Node2Index;
    std::vector<V> m_preNode;
    std::vector<E> m_TargetDist;

};


template<class V,class E = double >
class Data
{
public:
    Data()= default;
    Data(V _node, E _dist){node = _node; dist = _dist;}
    V node;
    E dist;
};
template<class V,class E = double >
class CompareData {
public:
    bool operator()( Data<V,E> a, Data<V,E> b) {
        // 由于std::priority_queue是最大堆，我们需要反转比较以实现最小堆
        return a.dist > b.dist;
    }
};

template<class V,class E  = double >
class PriorityQueue
{
public:
    PriorityQueue()= default;

    void push(Data<V,E> data){que.push(data);}

    Data<V,E> top(){return que.top();}

    bool empty(){return que.empty();}
    void pop(){ que.pop();}
private:
    std::priority_queue<Data<V,E>,std::vector<Data<V,E>>,CompareData<V,E>> que;
};